package com.zttek.photosShareProject.modules.service.share.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.zttek.photosShareProject.common.json.CommentVO;
import com.zttek.photosShareProject.common.json.UserVO;
import com.zttek.photosShareProject.common.json.VO;
import com.zttek.photosShareProject.common.myException.DBException;
import com.zttek.photosShareProject.modules.mapper.CommentMapper;
import com.zttek.photosShareProject.modules.mapper.CommentPraiseMapper;
import com.zttek.photosShareProject.modules.model.*;
import com.zttek.photosShareProject.modules.service.login.IUserService;
import com.zttek.photosShareProject.modules.service.share.ICommentService;
import com.zttek.photosShareProject.modules.service.share.IInfoService;
import com.zttek.photosShareProject.modules.service.share.IShareService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@SuppressWarnings("unchecked")
public class CommentService implements ICommentService {

    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    private CommentPraiseMapper praiseMapper;

    @Autowired
    private IShareService shareService;

    @Autowired
    private IInfoService infoService;

    @Autowired
    private IUserService userService;


    @Transactional
    @Override
    public Comment newReply(String content, Long[] atIds, Long shareId, Long userId, Long targetId) throws Exception {
        Comment comment = new Comment();
        comment.setContent(content);
        comment.setAtUserIds(VO.mergeIds(atIds));
        comment.setShareId(shareId);
        comment.setUserId(userId);
        comment.setTargetId(targetId);
        Date date = new Date();
        comment.setCreateTime(date);
//        commentInsert(comment);
        commentMapper.insert(comment);

        if (targetId != null) {
//            long targetUserId = commentSelectById(targetId).getUserId();
            long targetUserId = commentMapper.selectById(targetId).getUserId();
            infoService.createUserInfoForComment(targetUserId, userId, targetId, IInfoService.REPLY);
        } else {
            long targetUserId = shareService.selectShare(shareId).getUserId();
            infoService.createUserInfoForShare(targetUserId, userId, shareId, IInfoService.REPLY);
        }

        shareService.updateCommentCount(shareId, true);
        if (atIds != null)
            for (Long atId : atIds) {
                infoService.createUserInfoForComment(atId, userId, comment.getId(), IInfoService.AT);
            }

        return comment;
    }

    @Override
    public Comment selectComment(Long commentId) throws Exception {
//        Comment comment = commentSelectById(commentId);
        return commentMapper.selectById(commentId);
    }

    @Override
    public Comment selectFastComment(Long shareId) throws Exception {
        EntityWrapper<Comment> ew = new EntityWrapper<>();
        ew.where("valid = 1").and("share_id = {0}", shareId);
//        List<Comment> list = commentSelectPage(page, ew);
        List<Comment> list = commentMapper.selectList(ew);
        if (list.size() < 1)
            return null;
        return list.get(0);
    }

    @Override
    public Page<Comment> getShareComment(Page<Comment> page, Long shareId) throws Exception {
        EntityWrapper<Comment> ew = new EntityWrapper<>();
        ew.where("valid = 1").and("share_id = {0}", shareId);
//        List<Comment> list = commentSelectPage(page, ew);
        List<Comment> list = commentMapper.selectPage(page, ew);
        page.setRecords(list);
        return page;
    }

    @Transactional
    @Override
    public void updatePraiseCount(Long commentId, boolean isPlus) throws Exception {
//        Share share = shareSelectById(commentId);
        Comment comment = commentMapper.selectById(commentId);
        int i = comment.getTotalPraise();
        if (isPlus)
            i++;
        else i--;
        comment.setTotalPraise(i);

//        shareUpdate(share);
        commentMapper.updateById(comment);
    }

    @Transactional
    @Override
    public void praise(Long commentId, Long userId, boolean isPlus) throws Exception {
        updatePraiseCount(commentId, isPlus);

        EntityWrapper<CommentPraise> ew = new EntityWrapper<>();
        ew.where("comment_id={0}", commentId).and("user_id={0}", userId);
        CommentPraise commentPraise;
        Date date = new Date();
//        List<SharePraise> list = praiseSelectList(ew);
        List<CommentPraise> list = praiseMapper.selectList(ew);
        if (list == null || list.size() == 0) {
            commentPraise = new CommentPraise();
            commentPraise.setCommentId(commentId);
            commentPraise.setUserId(userId);
            commentPraise.setCreateTime(date);
//            praiseInsert(sharePraise);
            praiseMapper.insert(commentPraise);
        } else {
            commentPraise = list.get(0);
        }

        if (isPlus) {
            commentPraise.setValid(1);

            Comment targetComment = selectComment(commentId);
            infoService.createUserInfoForShare(targetComment.getUserId(), userId, commentId, IInfoService.PRAISE);
        } else {
            commentPraise.setValid(0);
            commentPraise.setDeleteTime(date);
        }

//        praiseUpdate(sharePraise);
        praiseMapper.updateById(commentPraise);
    }

    @Override
    public List<Long> getUserPraiseList(Long userId) throws Exception {
        List<Long> list = new ArrayList<>();
        EntityWrapper<CommentPraise> ew = new EntityWrapper<>();
        ew.eq("user_id", userId).and("valid = 1");
//        List<SharePraise> sharePraises = praiseSelectList(ew);
        List<CommentPraise> commentPraises = praiseMapper.selectList(ew);
        for (CommentPraise commentPraise : commentPraises) {
            list.add(commentPraise.getCommentId());
        }
        return list;
    }

    @Transactional
    @Override
    public void deleteComment(Long commentId) throws Exception {
//        Comment comment = commentSelectById(commentId);
        Comment comment = commentMapper.selectById(commentId);
        comment.setValid(0);
        comment.setDeleteTime(new Date());
//        commentUpdate(comment);
        commentMapper.updateById(comment);

        shareService.updateCommentCount(comment.getShareId(), false);
    }

    @Override
    public CommentVO comment2VO(Comment comment, Long userId, boolean needReplyContent) throws Exception {
        List<Long> praiseList;
        boolean hasPraise = false;
        if (userId != null) {
            praiseList = getUserPraiseList(userId);
            hasPraise = praiseList.contains(comment.getId());
        }
        return comment2VO(comment, hasPraise, needReplyContent);
    }

    private CommentVO comment2VO(Comment comment, boolean hasPraise, boolean needReplyContent) throws Exception {
        CommentVO commentVO = null;
        User user = null, replyUser = null;
        UserVO userVO = null, replyUserVO = null;
        user = userService.selectUserById(comment.getUserId());
        userVO = userService.user2VO(user, null, true);
        UserVO[] atList = shareService.atIds2VOs(comment.getAtUserIds());
        String replyContent = null;
        if (comment.getTargetId() != null) {
            if (needReplyContent) {
                replyContent = selectComment(comment.getTargetId()).getContent();
            }
            replyUser = userService.selectUserById(selectComment(comment.getTargetId()).getUserId());
            replyUserVO = userService.user2VO(replyUser, null, false);
        }
        commentVO = new CommentVO(comment, userVO, replyUserVO, replyContent, hasPraise, atList);
        return commentVO;
    }

    @Override
    public List<CommentVO> comment2VO(List<Comment> comments, Long userId, boolean needReplyContent) throws Exception {
        List<CommentVO> list = new ArrayList<>();
        List<Long> praiseList = new ArrayList<>();
        ;
        if (userId != null) {
            praiseList = getUserPraiseList(userId);
        }
        for (Comment comment : comments) {
            list.add(comment2VO(comment, praiseList.contains(comment.getId()), needReplyContent));
        }
        return list;
    }

    @Deprecated
    private Comment commentSelectById(Long commentId) {
        Comment comment = null;
        try {
            commentMapper.selectById(commentId);
        } catch (Exception e) {
            e.printStackTrace();
            throw new DBException(DBException.COMMENT_SELECT_FAILURE);
        }
        return comment;
    }

    @Deprecated
    private void commentInsert(Comment comment) {
        try {
            commentMapper.insert(comment);
        } catch (Exception e) {
            e.printStackTrace();
            throw new DBException(DBException.COMMENT_INSERT_FAILURE);
        }
    }

    @Deprecated
    private List<Comment> commentSelectPage(Page<Comment> page, EntityWrapper<Comment> ew) {
        List<Comment> list = null;
        try {
            list = commentMapper.selectPage(page, ew);
        } catch (Exception e) {
            throw new DBException(DBException.COMMENT_SELECT_FAILURE);
        }
        return list;
    }

    @Deprecated
    private void commentUpdate(Comment comment) {
        try {
            commentMapper.updateById(comment);
        } catch (Exception e) {
            throw new DBException(DBException.COMMENT_UPDATE_FAILURE);
        }
    }
}
